package com.ursu.client.presenter;

import com.gwtplatform.dispatch.shared.DispatchAsync;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.ProxyStandard;
import com.gwtplatform.mvp.client.annotations.NameToken;
import com.ursu.client.place.NameTokens;
import com.ursu.shared.FieldVerifier;
import com.ursu.shared.User;
import com.ursu.shared.Constants;
import com.ursu.shared.actions.CreateUser;
import com.ursu.shared.actions.CreateUserResult;
import com.gwtplatform.mvp.client.proxy.PlaceManager;
import com.gwtplatform.mvp.client.proxy.PlaceRequest;
import com.gwtplatform.mvp.client.proxy.ProxyPlace;
import com.google.inject.Inject;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.gwtplatform.mvp.client.proxy.RevealRootContentEvent;

public class CreateAccountPresenter
extends
Presenter<CreateAccountPresenter.MyView, CreateAccountPresenter.MyProxy> {

	public interface MyView extends View {

		public TextBox getUsernameBox();
		public TextBox getEmailBox() ;
		public PasswordTextBox getPasswordBox() ;
		public PasswordTextBox getConfPasswordBox();
		public Button getCreateAccountBtn() ;
		public Label getErrorLabel();
	}

	@ProxyStandard
	@NameToken(NameTokens.createaccount)
	public interface MyProxy extends ProxyPlace<CreateAccountPresenter> {
	}

	@Inject
	PlaceManager placeManager;
	@Inject DispatchAsync dispatchAsync;
	@Inject
	public CreateAccountPresenter(final EventBus eventBus, final MyView view,
			final MyProxy proxy) {
		super(eventBus, view, proxy);
	}

	@Override
	protected void revealInParent() {
		RevealRootContentEvent.fire(this, this);
	}

	@Override
	protected void onBind() {
		super.onBind();
		addHandlers();
	}

	@Override
	protected void onReset() {
		super.onReset();
		resetViews();
	}


	private void resetViews() {
		getView().getUsernameBox().setText("");
		getView().getEmailBox().setText("");
		getView().getPasswordBox().setText("");
		getView().getConfPasswordBox().setText("");
		
		getView().getErrorLabel().setText("");
		getView().getErrorLabel().removeStyleName("error");
		
	}

	private void addHandlers() {
		registerHandler(getView().getCreateAccountBtn().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				User user;

				if(verifyFields()){
					user = new User();
					createUserFomFields(user);
					
					CreateUser action = new CreateUser(user);
					dispatchAsync.execute(action, createUserCallback);

				}

			}
		}));
	}
	
	private AsyncCallback<CreateUserResult> createUserCallback = new AsyncCallback<CreateUserResult>() {

		@Override
		public void onFailure(Throwable caught) {
			// What to do if create user was unsuccessful 
			
		}

		@Override
		public void onSuccess(CreateUserResult result) {
			getView().getErrorLabel().setText("User created successfuly:\n "+ 
													"SessionId: "+result.getSessionId()+"\n"+
												"DatastoreId: "+ result.getDatastoreId()+"\n");
			
			PlaceRequest request = new PlaceRequest(NameTokens.getFirstpage());
			placeManager.revealPlace(request);
			
		}
	};

	protected void createUserFomFields(User userToFillFields) {
		

		userToFillFields.setUsername(getView().getUsernameBox().getText());
		userToFillFields.setEmail(getView().getEmailBox().getText());
		userToFillFields.setHashedPassword(getView().getPasswordBox().getText());

	}

	/**
	 * This is to check if the username and passwords match 
	 * the requirements ( length and required characters )
	 * @return {@code true} if the username and password are ok, {@code false} otherwise 
	 */
	protected boolean verifyFields() {
		boolean isValid = true;
		StringBuilder sb = new StringBuilder();
	
		if(!FieldVerifier.isValidUserName(getView().getUsernameBox().getText())){
			isValid = false;
			sb.append(Constants.USERNAME_ERROR);
		}
		if(!FieldVerifier.isValidPassword(getView().getPasswordBox().getText())){
			isValid = false;
			sb.append(Constants.PASSWORD_REGEX_ERROR);
		}
		if(!getView().getPasswordBox().getText().equals(getView().getConfPasswordBox().getText())){
			isValid = false;
			sb.append(Constants.PASSWORD_MATCH_ERROR);
		}
		if(isValid == false){
		getView().getErrorLabel().setStyleName("error");
		getView().getErrorLabel().setText(sb.toString());
		}
		return isValid;
		
	}
}
